package com.suning.sawp.service.impl.storeman;

import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.http.entity.mime.FormBodyPart;
import org.apache.http.entity.mime.content.InputStreamBody;
import org.apache.http.entity.mime.content.StringBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.google.gson.reflect.TypeToken;
import com.suning.framework.sedis.JedisAction;
import com.suning.framework.sedis.JedisClient;
import com.suning.nsf.sale.biz.posts.UserCommonService;
import com.suning.nsf.sale.biz.posts.dto.ResponseDTO;
import com.suning.nsfuaa.common.NsfuaaResult;
import com.suning.nsfuaa.employee.EmployeeService;
import com.suning.nsfuaa.employee.dto.EmpListOfOrgPos;
import com.suning.nsfuaa.employee.dto.Employee;
import com.suning.nsfuaa.employee.dto.EmployeeInfo;
import com.suning.nsfuaa.roleauth.RoleAuthService;
import com.suning.nsfuaa.roleauth.dto.AuthMenuInfo;
import com.suning.nsfuaa.roleauth.dto.EmpAuth;
import com.suning.nsfuaa.roleauth.dto.EmpLoginExt;
import com.suning.posts.remote.intf.PostsAuthService;
import com.suning.rsf.consumer.ServiceLocator;
import com.suning.sawp.constants.ClerkConstants;
import com.suning.sawp.constants.ConfigConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.dto.bi.BiStoreCateCompleteRate;
import com.suning.sawp.dto.bi.BiStoreKeeperSaleDataDto;
import com.suning.sawp.dto.bi.StoreManRealIncSum;
import com.suning.sawp.dto.common.OrgInfo;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.mainpush.ClerkMainPushSaleComplete;
import com.suning.sawp.dto.mainpush.GuideRankShowDto;
import com.suning.sawp.dto.mainpush.LastestChooseManReqDto;
import com.suning.sawp.dto.mainpush.RankingListDto;
import com.suning.sawp.dto.mainpush.SaleStatisticDto;
import com.suning.sawp.dto.mainpush.StoreCateSaleStatis;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.dto.mainpush.StoreMonSaleDetailDto;
import com.suning.sawp.dto.mainpush.StoreTaskCompleteDetail;
import com.suning.sawp.dto.mainpush.StoreTaskCompleteDto;
import com.suning.sawp.dto.mainpush.TaskStoreTempDto;
import com.suning.sawp.dto.storeman.Category;
import com.suning.sawp.dto.storeman.DjAuthMenuInfo;
import com.suning.sawp.dto.storeman.IndexCateSaleDto;
import com.suning.sawp.dto.storeman.IpAddress;
import com.suning.sawp.dto.storeman.RetCode;
import com.suning.sawp.dto.storeman.StoreLoginResultBean;
import com.suning.sawp.dto.storeman.StoreManAccount;
import com.suning.sawp.dto.storeman.StoreManIndexShowData;
import com.suning.sawp.dto.storeman.StoreRealTimeSale;
import com.suning.sawp.dto.storeman.StoreVo;
import com.suning.sawp.exception.MobileException;
import com.suning.sawp.intf.bi.BiDataDaoService;
import com.suning.sawp.intf.bi.BiKafkaRealTimeSaleService;
import com.suning.sawp.intf.bi.BiSaleAmountDaoService;
import com.suning.sawp.intf.dao.StoreManLoginLogDaoService;
import com.suning.sawp.intf.dao.task.TaskStoreAndClerkDaoService;
import com.suning.sawp.intf.maindiscode.MainDiscodeService;
import com.suning.sawp.intf.mainpush.LastestChooseManService;
import com.suning.sawp.intf.servicenum.ServiceNumService;
import com.suning.sawp.intf.store.StoreInfoService;
import com.suning.sawp.intf.storeman.StoreManService;
import com.suning.sawp.po.StoreManLoginLog;
import com.suning.sawp.po.bi.BIStaffPushTaskMonth;
import com.suning.sawp.po.bi.BIStaffSaleAllDay;
import com.suning.sawp.po.bi.BIStaffSaleAllMonth;
import com.suning.sawp.po.bi.BIStoreSaleAllDay;
import com.suning.sawp.po.bi.BIStoreSaleAllMonth;
import com.suning.sawp.po.bi.BIStoreSaleCateDay;
import com.suning.sawp.po.bi.BIStoreSaleCateMonth;
import com.suning.sawp.po.mainpush.MainPushTask;
import com.suning.sawp.po.store.StaffInfo;
import com.suning.sawp.po.store.StoreInfo;
import com.suning.sawp.po.task.TaskClerk;
import com.suning.sawp.service.impl.task.StoreTaskBIShowService;
import com.suning.sawp.service.task.dto.BIStoreTask;
import com.suning.sawp.service.util.AESUtils;
import com.suning.sawp.service.util.ConfigUtil;
import com.suning.sawp.service.util.DJStringUtils;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.service.util.GsonUtils;
import com.suning.sawp.service.util.HttpClientUtil;
import com.suning.sawp.service.util.SCMConfigUtil;
import com.suning.sawp.service.util.SingleThreadFactory;
import com.suning.vgs.follow.remote.intf.StoreManRemoteService;
import com.suning.vgs.follow.remote.store.ActiveIndicator;
import com.suning.vgs.follow.remote.store.ReturnMsg.RetFlag;
import com.suning.vgs.follow.remote.store.ShopGuideDto;
import com.suning.vgs.follow.remote.store.StoreManBaseDto;
import com.suning.vgs.follow.remote.store.UpdateHeadPicRetDto;

import redis.clients.jedis.Jedis;

@Service("storeManService")
public class StoreManServiceImpl implements StoreManService {

	private static final Logger LOGGER = LoggerFactory.getLogger(StoreManServiceImpl.class);

	// 调用rms用户属性系统失败
	private static final String RMS_PROFILE_ERROR = "2013";

	// 工号输入错误
	private static final String CLERK_NUM_ERROR = "0015";

	private static final String SUCCESS = "1";

	private static final String UPLOAD_HEAD_PIC_FAIL = "0";

	private static final String YDG = "1";

	/**
	 * AAS接口成功返回的代码
	 */
	private static final String SUCC_RESPONSE_CODE = "10000000";

	/**
	 * 店员附属信息缓存时间
	 */
	private static final int ATTACH_INFO_EXPIRE_TIME = 24 * 60 * 60;

	/**
	 * 默认首页缓存时间设为30分钟
	 */
	private static final int STORE_MAN_INDEX_EXPIRE_TIME = 30 * 60;

	/**
	 * 店员附属信息缓存key前缀
	 */
	private static final String ATTACH_INFO_PREFIX = "com.suning.sawp.storeman.attachInfo";

	/**
	 * 店员首页信息缓存key前缀
	 */
	private static final String STORE_MAN_INDEX_PREFIX = "com.suning.sawp.storeman.indexshow";

	/**
	 * 店+APP在NSF-UUA中的系统编码
	 */
	private static final String DJ_APP = "DJAPP";

	private static final BigDecimal ZERO = new BigDecimal(0);

	/**
	 * 兼品类
	 */
	private static final String JIAN_CATEGORY = "9";

	/**
	 * 全品类
	 */
	private static final String QUAN_CATEGORY = "8";

	/**
	 * 快销门店类型
	 */
	@SuppressWarnings("serial")
	private static final Set<String> FAST_SALE_STORE_TYPE = new HashSet<String>() {
		{
			add("20");
			add("21");
			add("22");
		}
	};

	@Value("#{ipsConfig[impserver_ip]}")
	private String impserverIp;

	@Value("#{ipsConfig[impserver_port]}")
	private String impserverPort;

	@Value("#{ipsConfig[ofsserver_ip]}")
	private String ofsserverIp;

	@Value("#{ipsConfig[ofsserver_port]}")
	private String ofsserverPort;

	@Value("#{ipsConfig[cabserver_ip]}")
	private String cabserverIp;

	@Value("#{ipsConfig[cabserver_port]}")
	private String cabserverPort;

	@Value("#{ipsConfig[nginxserver_ip]}")
	private String nginxserverIp;

	@Value("#{ipsConfig[upload_storeman_headpic_url]}")
	private String uploadHeadpicUrl;

	@Value("#{ipsConfig[aasGetTokenUrl]}")
	private String assGetTokenUrl;

	@Autowired
	StoreManRemoteService storeManRemoteService;

//	@Resource
//	RmsRemoteService rmsRelationshipService;

	@Resource
	StoreManLoginLogDaoService storeManLoginLogDaoService;

	@Resource
	ServiceNumService serviceNumService;

	@Resource
	JedisClient jedisClient;

	@Resource
	BiSaleAmountDaoService biSaleAmountDaoService;

	@Resource
	TaskStoreAndClerkDaoService taskStoreAndClerkDaoService;

	@Resource
	BiDataDaoService biDataDaoService;

	@Resource
	LastestChooseManService lastestChooseManService;

	@Resource
	StoreTaskBIShowService storeTaskBIShowService;

	@Resource
	StoreInfoService storeInfoService;

	@Resource
	BiKafkaRealTimeSaleService biKafkaRealTimeSaleService;

	@Resource
	MainDiscodeService mainDiscodeService;

	private EmployeeService employeeService = ServiceLocator.getService(EmployeeService.class, "");

	private RoleAuthService roleAuthService = ServiceLocator.getService(RoleAuthService.class, "");

	private UserCommonService userCommonService = ServiceLocator.getService(UserCommonService.class, "default");
	
	private PostsAuthService postsAuthService = ServiceLocator.getService(PostsAuthService.class, "postsAuthService");
	
	@Override
	public StoreLoginResultBean staffLogin(String staffId, String requestIp, String deviceName, String djDeviceId) {
		StoreManBaseDto userBean = null;
		LOGGER.info("-----staffLogin----in,staffId:{}", staffId);
		try {
			com.suning.vgs.follow.remote.store.ReturnMsg<StoreManBaseDto> result = storeManRemoteService.getStoreManInfoWhenLogin(staffId);

			if (null == result) {
				LOGGER.warn("invoke rms getStoreManInfoWhenLogin result is null, staffId:{}", staffId);
				throw new MobileException(RMS_PROFILE_ERROR, "系统异常");
			}
			String retFlag = result.getRetFlag();
			if (RetFlag.SUCCESS.equals(retFlag)) {
				userBean = result.getData();
			} else {
				LOGGER.warn("invoke rms getStoreManInfoWhenLogin result.retFlag is fail, staffId:{}", staffId);
				throw new MobileException(result.getErrorCode(), result.getErrorMsg());
			}

		} catch (Exception e) {
			LOGGER.warn("dubbo invoke rms getStoreManInfoByStaffId excepiton!", e);
			throw new MobileException(RMS_PROFILE_ERROR, "系统异常");
		}

		if (userBean == null) {
			LOGGER.warn("user not exsit, staffId=" + staffId);
			throw new MobileException(CLERK_NUM_ERROR, "系统异常");
		}

		Employee employee = employeeService.queryEmployeeBasicInfo(staffId);
		LOGGER.info("queryEmployeeBasicInfo,employee:" + employee);
		StoreLoginResultBean loginResultBean = new StoreLoginResultBean();
		StaffInfo staffInfo = storeInfoService.queryStaffInfoByStaffId(staffId);
		if (staffInfo == null) {
			staffInfo = new StaffInfo();
		}
		List<Category> categoryes = new ArrayList<Category>();
		if (staffInfo != null && StringUtils.isNotBlank(staffInfo.getLastPositionId())) {
			categoryes = tranferStoreInfo(staffInfo.getLastPositionId(), employee);
		}
		loginResultBean.setOrgId(employee.getOrgId());
		changeToBean(categoryes, staffInfo, userBean, loginResultBean);
		LOGGER.info("-----staffLogin----getStoreManInfoWhenLogin, staffId:{}", staffId);
		// 查询所有服务号ID
		List<String> serviceNumIds = serviceNumService.queryServiceNumCloudGuideIds();
		loginResultBean.setServiceNumIds(serviceNumIds);
		/*LOGGER.info("-----staffLogin----getToken, staffId:{}", staffId);
		// 调用aas接口:servlet/getToken.do获取登录token
		String authId = getToken(staffId, YDG);
		loginResultBean.setAuthId(authId);*/

		loginResultBean.setSuccessFlg(SUCCESS);

		LOGGER.info("-----staffLogin----recordLoginLog, staffId:{}", staffId);
		// 记录登录日志
		try {
			// 捕获异常，不影响主流程
			recordLoginLog(requestIp, deviceName, djDeviceId, staffId);
		} catch (Exception e) {
			LOGGER.error("StoreManService.staffLogin recordLoginLog error.", e);
		}
		// 查询店员所属菜单编码，调NSF-UUA接口获取
		LOGGER.info("-----staffLogin----getEmpAuth, staffId:{}", staffId);
		try {
			EmpAuth empAuth = roleAuthService.getEmpAuth(DJ_APP, staffId);
			LOGGER.info("roleAuthService.getEmpAuth, EmpAuth:{}", empAuth);
			StoreManAccount storeManAccount = loginResultBean.getAccount();
			storeManAccount.setPositionId("");
			storeManAccount.setPositionName("");
			storeManAccount.setStoreCode("");
			storeManAccount.setLastOrgId("");
			storeManAccount.setLastRoleType("");
			// 设置可选角色信息，客户端根据对应的岗位信息选择对应的权限
			if (null != empAuth && NsfuaaResult.SUCCESS == empAuth.getStatus()) {
			    List<DjAuthMenuInfo> positionList = new ArrayList<DjAuthMenuInfo>();
				if (CollectionUtils.isNotEmpty(empAuth.getEmpAuthList())) {
					// 将副店长岗位编码换成店长岗位编码
					for (AuthMenuInfo item : empAuth.getEmpAuthList()) {
						if (item != null && item.getEmpLoginExt() != null) {
							EmpLoginExt detail = item.getEmpLoginExt();
							if (ClerkConstants.DEPUTY_STORE_KEEPER.equals(detail.getPostionId())) {
								detail.setPostionId(ClerkConstants.STORE_KEEPER);
							}
							// 设置缺省门店名称
							if (StringUtils.isBlank(detail.getOrgDisplayName())) {
								detail.setOrgDisplayName(ClerkConstants.DEFAULT_STORE_NAME);
							}

							// 设置缺省门店编码
							if (StringUtils.isBlank(detail.getOrgCode())) {
								detail.setOrgCode("");
							}
							// 如果在可选岗位中包含店员当前岗位的话则更新对应信息,同一个岗位存在不同门店的情况
							staffInfo.setStoreCode(StringUtils.isBlank(staffInfo.getStoreCode()) ? "" : staffInfo.getStoreCode());
							staffInfo.setOrgId(StringUtils.isBlank(staffInfo.getOrgId()) ? "" : staffInfo.getOrgId());
							staffInfo.setRoleType(StringUtils.isBlank(staffInfo.getRoleType()) ? "" : staffInfo.getRoleType());
							if (staffInfo != null && StringUtils.isNotBlank(staffInfo.getLastPositionId()) && staffInfo.getLastPositionId().equals(detail.getPostionId())
									&& staffInfo.getOrgId().equals(detail.getOrgId()) && staffInfo.getRoleType().equals(detail.getRoleType())) {
								storeManAccount.setPositionId(staffInfo.getLastPositionId());
								storeManAccount.setPositionName(staffInfo.getLastPositionName());
								storeManAccount.setStoreCode(staffInfo.getStoreCode());
								storeManAccount.setLastOrgId(staffInfo.getOrgId());
								storeManAccount.setLastRoleType(staffInfo.getRoleType());
							}
							// 将UUA的信息塞到DjAuthMenuInfo中
	                        DjAuthMenuInfo authMenuInfo = new DjAuthMenuInfo(item);
	                        // 查询门店所属类型
	                        if (StringUtils.isNotBlank(detail.getOrgCode()) && detail.getOrgCode().length() == 4) {
	                            StoreInfo storeInfo = storeInfoService.queryStoreByCode(detail.getOrgCode());
	                            if (null != storeInfo) {
	                                authMenuInfo.getEmpLoginExt().setStoreType(storeInfo.getStoreTypeCode());
	                            }
	                        }
	                        // 调用POS取城市编码、区域编码
	                        if (OrgInfo.ORG_LEVEL.STORE_LEVEL.equals(detail.getOrgLevelCode())) {
	                            // 只有门店层级才去查询。pos的门店城市区域信息
	                            ResponseDTO<Object> response = userCommonService.findCityAreaInfoByStoreCode(detail.getOrgCode(), detail.getOrgLevelCode());
	                            if (null != response && CollectionUtils.isEmpty(response.getErrors())) {
	                                // 说明调用POS取城市编码、区域编码成功了
	                                List<StoreVo> stores = GsonUtils.fromJson(response.getResult().toString(), new TypeToken<List<StoreVo>>() {
	                                });
	                                if (CollectionUtils.isNotEmpty(stores)) {
	                                    for (StoreVo vo : stores) {
	                                        if (StringUtils.isNotEmpty(vo.getCityCode())
	                                                && detail.getOrgCode().equals(vo.getStoreCode())) {
	                                            authMenuInfo.getEmpLoginExt().setAreaCode(vo.getAreaCode());
	                                            authMenuInfo.getEmpLoginExt().setCityCode(vo.getCityCode());
	                                            authMenuInfo.getEmpLoginExt().setPosUserId((isPromotion(detail.getPostionId()) ? ClerkConstants.USER_PREFIX_Z : ClerkConstants.USER_PREFIX_Y) + staffId);
	                                            break;
	                                        }
	                                    }
	                                }
	                            }
	                        }
	                        
	                        positionList.add(authMenuInfo);
						}
					}
					loginResultBean.setPositionList(positionList);
				}
			} else {
				LOGGER.error("invoke nsf-uua get menuIds error, staffId:{}", staffId);
			}
		} catch (Exception e) {
			LOGGER.error("invoke nsf-uua get menuIds error, staffId:{}", staffId, e);
		}
		LOGGER.info("-----staffLogin----out, staffId:{}", staffId);
		// 工号-岗位-门店-品类信息缓存至redis缓存
		return loginResultBean;
	}

	/**
	 * 
	 * 功能描述:判断是否为促销员角色 <br>
	 * 〈功能详细描述〉
	 *
	 * @param posId
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private boolean isPromotion(String posId) {
        if (ClerkConstants.SALES_PROMOTION.equals(posId)) {
            return true;
        }
        return false;
    }
	
	/**
	 * 
	 * 功能描述: 记录登录日志<br>
	 * 〈功能详细描述〉
	 *
	 * @param requestIp
	 * @param deviceName
	 * @param djDeviceId
	 * @param staffId
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private void recordLoginLog(String requestIp, String deviceName, String djDeviceId, final String staffId) {
		// 设备ID解密
		String deviceId = AESUtils.decodeAndDecrypt(djDeviceId, ConfigConstants.AES_KEY);

		StoreManLoginLog loginLog = new StoreManLoginLog();
		loginLog.setDeviceId(deviceId);
		loginLog.setDeviceName(deviceName);
		loginLog.setLoginIp(requestIp);
		loginLog.setStaffId(staffId);
		loginLog.setLoginTime(new Date());
		storeManLoginLogDaoService.addLoginLog(loginLog);
		// 异步清除超过30天的登录日志
		SingleThreadFactory.getExecutorService().execute(new Runnable() {
			@Override
			public void run() {
				Date date = DateUtils.getZeroPoint(DateUtils.getNextDay(new Date(), -30));
				storeManLoginLogDaoService.deleteLoginLogBeforeDate(staffId, date);
			}
		});
	}

	/**
	 * 
	 * 功能描述: 调ass 获取Token
	 * 
	 * @param userId
	 * @return
	 * @throws MobileException
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private String getToken(String userName, String appType) {
		String token = "";
		String getTokenParam = "userName=" + userName + "&appType=" + appType;
		try {
			String getTokenResult = HttpClientUtil.getData(assGetTokenUrl + "?" + getTokenParam);
			LOGGER.info("ass 获取Token信息返回结果:" + getTokenResult);
			if (StringUtils.isNotBlank(getTokenResult)) {
				TypeToken<Map<String, Object>> typeToken = new TypeToken<Map<String, Object>>() {
				};
				Map<String, Object> tokenResultMap = GsonUtils.fromJson(getTokenResult, typeToken);
				if (SUCC_RESPONSE_CODE.equals(tokenResultMap.get("retCode").toString())) {
					token = tokenResultMap.get("token").toString();
				} else {
					LOGGER.error("ass 返回Token信息错误:" + getTokenResult);
				}
			} else {
				LOGGER.error("ass 返回Token信息为空!");
			}
		} catch (Exception e1) {
			LOGGER.error("ass 获取Token接口异常!", e1);
		}
		return token;
	}

	/**
	 * 
	 * 加载blh写死的静态资源路径<br>
	 * 〈功能详细描述〉
	 * 
	 * @param loginResultBean
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
//	private void setIps(StoreLoginResultBean loginResultBean) {
//		IpAddress cabinfo = new IpAddress();
//		cabinfo.setIp(cabserverIp);
//		cabinfo.setPort(cabserverPort);
//		loginResultBean.setCabinfo(cabinfo);
//
//		IpAddress ofsinfo = new IpAddress();
//		ofsinfo.setIp(ofsserverIp);
//		ofsinfo.setPort(ofsserverPort);
//		loginResultBean.setOfsinfo(ofsinfo);
//
//		IpAddress impinfo = new IpAddress();
//		impinfo.setIp(impserverIp);
//		impinfo.setPort(impserverPort);
//		loginResultBean.setImpinfo(impinfo);
//
//		IpAddress nginxinfo = new IpAddress();
//		nginxinfo.setIp(nginxserverIp);
//		loginResultBean.setNginxinfo(nginxinfo);
//	}

	private static void changeToBean(List<Category> categoryes, StaffInfo staffInfo, StoreManBaseDto userBean, StoreLoginResultBean resBean) {
		try {
			resBean.setAccount(new StoreManAccount(userBean, staffInfo, categoryes));
		} catch (Exception e) {
			LOGGER.warn("copyProperties failed", e);
		}

		resBean.setRetCode(RetCode.SUCCESS.code.toString());
	}

	@Override
	public ReturnMsg<ActiveIndicator> getActiveIndicator(String staffId) {
		ReturnMsg<ActiveIndicator> msg = new ReturnMsg<ActiveIndicator>();
		try {
			// 判断参数为空的情况
			if (StringUtils.isBlank(staffId)) {
				msg.setError(ErrorCodeConstants.ERR_0007);
			}
			ActiveIndicator data = storeManRemoteService.getActiveIndicator(staffId);
			msg.setData(data);
		} catch (Exception e) {
			msg.setError(ErrorCodeConstants.ERR_0002);
			LOGGER.error("获取云导购店员用户活跃度指标出错，参数:", staffId, e);
		}

		return msg;
	}

	@Override
	public ReturnMsg<List<ShopGuideDto>> getAllProductCategories() {
		ReturnMsg<List<ShopGuideDto>> msg = new ReturnMsg<List<ShopGuideDto>>();
		try {
			List<ShopGuideDto> datas = storeManRemoteService.getAllProductCategories();
			msg.setData(datas);
		} catch (Exception e) {
			msg.setError(ErrorCodeConstants.ERR_0002);
			LOGGER.error("获取所有商品品类信息，参数:", e);
		}

		return msg;
	}

	@Override
	public ReturnMsg<String> updateUserInfo(String staffId, String productCatagories) {
		ReturnMsg<String> msg = new ReturnMsg<String>();
		// 更改店员品类信息
		if (StringUtils.isNotBlank(productCatagories)) {
			try {
				String[] args = productCatagories.split(",");
				List<String> categoryList = Arrays.asList(args);
				String result = storeManRemoteService.modifyStoreManCategoryInfo(staffId, categoryList);
				if (!SUCCESS.equals(result)) {
					// 更新品类失败，一般由于品类已存在导购
					msg.setError(ErrorCodeConstants.ERR_1006, result);
				}
			} catch (Exception e) {
				msg.setError(ErrorCodeConstants.ERR_1007);
				LOGGER.error("修改云导购店员所负责品类信息失败", e);
			}
		}

		return msg;
	}

	@Override
	public ReturnMsg<UpdateHeadPicRetDto> uploadHeadPic(String staffId, InputStream inputStream) {
		ReturnMsg<UpdateHeadPicRetDto> msg = new ReturnMsg<UpdateHeadPicRetDto>();
		if (null != inputStream) {
			try {
				String result = uploadImg(inputStream, staffId);
				if (UPLOAD_HEAD_PIC_FAIL.equals(result)) {
					// 头像上传失败
					msg.setError(ErrorCodeConstants.ERR_1008);
				} else {
					// 成功返回更改后的头像类型和头像编号
					UpdateHeadPicRetDto picRetDto = GsonUtils.fromJson(result, UpdateHeadPicRetDto.class);
					msg.setData(picRetDto);
				}
			} catch (Exception e) {
				msg.setError(ErrorCodeConstants.ERR_0002);
				LOGGER.error("上传店员用户头像失败", e);
			}
		}

		return msg;
	}

	/**
	 * 
	 * 功能描述: 上传头像至文件服务器<br>
	 * 〈功能详细描述〉 成功返回1；失败返回0
	 * 
	 * @param inputStream
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private String uploadImg(InputStream inputStream, String staffId) {
		String imgResult = null;
		try {
			// 获取请求地址URL
			String postUrl = uploadHeadpicUrl;
			// 新建List<FormBodyPart>
			List<FormBodyPart> multipartformData = new ArrayList<FormBodyPart>();
			multipartformData.add(new FormBodyPart("staffId", new StringBody(staffId, Charset.forName("UTF-8"))));
			multipartformData.add(new FormBodyPart("imgData", new InputStreamBody(inputStream, "")));
			// 发送求取获取结果
			imgResult = HttpClientUtil.postData(postUrl, multipartformData);
		} catch (Exception e) {
			LOGGER.error("StoreManService.uploadImg error", e);
		}

		return imgResult;
	}

	@Override
	public void addStoreManAttachInfo2Cache(StoreManDto attachInfo) {
		final String json = GsonUtils.toJson(attachInfo, false);
		final String key = ATTACH_INFO_PREFIX + attachInfo.getStaffId();
		jedisClient.execute(new JedisAction<String>() {
			@Override
			public String doAction(Jedis jedis) {
				jedis.setex(key, ATTACH_INFO_EXPIRE_TIME, json);
				return null;
			}
		});
	}

	@Override
	public void removeStoreManAttachInfoCache(String staffId) {
		final String key = ATTACH_INFO_PREFIX + staffId;
		jedisClient.execute(new JedisAction<String>() {
			@Override
			public String doAction(Jedis jedis) {
				jedis.del(key);
				return null;
			}
		});
		// 通知POSTS删除登录缓存信息
        postsAuthService.removePostsLoginCache(staffId);
	}

	/**
	 * 查询员工数据
	 */
	@Override
	public StoreManDto queryStoreManAttachInfo(String staffId) {
		final String key = ATTACH_INFO_PREFIX + staffId;
		String json = jedisClient.execute(new JedisAction<String>() {
			@Override
			public String doAction(Jedis jedis) {
				return jedis.get(key);
			}
		});
		if (StringUtils.isNotBlank(json)) {
			// redis中缓存信息尚未消失，
			StoreManDto man = GsonUtils.fromJson(json, StoreManDto.class);
			if (null != man) {
				return man;
			}
		}
		// 查询DB
		// 查询com.suning.vgs.follow.remote.store.ReturnMsg<StoreManBaseDto>
		// result = storeManRemoteService
		// 查询 .getStoreManInfoWhenLogin(staffId);
		// 查询StoreManBaseDto baseDto = result.getData();

		// 员工数据
		Employee employee = employeeService.queryEmployeeBasicInfo(staffId);

		// 登录记录
		StaffInfo staffInfo = storeInfoService.queryStaffInfoByStaffId(staffId);
		if (null == staffInfo || StringUtils.isBlank(staffInfo.getLastPositionId())) {
			LOGGER.error("queryStoreManAttachInfo , queryStaffInfoByStaffId is null : staffid:{}", staffId);
			throw new MobileException(RMS_PROFILE_ERROR, "岗位信息为空,请重新登录");
		}

		// 格式化门店编码
		staffInfo.setStoreCode(StringUtils.isBlank(staffInfo.getStoreCode()) ? "" : staffInfo.getStoreCode());
		staffInfo.setOrgId(StringUtils.isBlank(staffInfo.getOrgId()) ? "" : staffInfo.getOrgId());

		// 根据岗位,转换品类数据
		List<Category> categoryes = tranferStoreInfo(staffInfo.getLastPositionId(), employee);

		EmpLoginExt detail = new EmpLoginExt();
		try {
			EmpAuth empAuth = roleAuthService.getEmpAuth(DJ_APP, staffId);
			// 设置可选角色信息，客户端根据当前的岗位信息选择对应的权限
			if (null != empAuth && NsfuaaResult.SUCCESS == empAuth.getStatus() && CollectionUtils.isNotEmpty(empAuth.getEmpAuthList())) {
				// 比对岗位数据
				EmpLoginExt authEmp = getEmpExt(empAuth.getEmpAuthList(), staffInfo);
				if (null != authEmp) {
					detail = authEmp;
				}
			} else {
				LOGGER.error("invoke nsf-uua get menuIds error, staffId:{}", staffId);
			}
		} catch (Exception e) {
			LOGGER.error("invoke nsf-uua get menuIds error, staffId:{}", staffId, e);
		}

		StoreManDto manDto = new StoreManDto(null, employee, categoryes, detail);
		// 查询门店信息
		if (StringUtils.isNotBlank(manDto.getStoreCode())) {
			StoreInfo storeInfo = storeInfoService.queryStoreByCode(manDto.getStoreCode());
			String saleRegionCode = mainDiscodeService.queryRegion5CdBy8Cd(manDto.getRegionCode());
			manDto.setSaleRegionCode(saleRegionCode);
			if (null != storeInfo) {
				manDto.setStoreLevel(storeInfo.getStoreLevel());
				manDto.setOrgBranchCode(storeInfo.getBranchCode());
				manDto.setStoreTypeCode(storeInfo.getStoreTypeCode());
				manDto.setStoreTypeName(storeInfo.getStoreTypeName());
				// 调用POS取城市编码、区域编码
                if (OrgInfo.ORG_LEVEL.STORE_LEVEL.equals(detail.getOrgLevelCode())) {
                    // 只有门店层级才去查询。pos的门店城市区域信息
                    ResponseDTO<Object> response = null;
                    try {
                        response = userCommonService.findCityAreaInfoByStoreCode(detail.getOrgCode(), detail.getOrgLevelCode());
                    } catch (Exception e) {
                        LOGGER.error("queryStoreManAttachInfo userCommonService.findCityAreaInfoByStoreCode ERROR", e);
                    }
                    
                    if (null != response && CollectionUtils.isEmpty(response.getErrors())) {
                        // 说明调用POS取城市编码、区域编码成功了
                        List<StoreVo> stores = GsonUtils.fromJson(response.getResult().toString(), new TypeToken<List<StoreVo>>() {
                        });
                        if (CollectionUtils.isNotEmpty(stores)) {
                            for (StoreVo vo : stores) {
                                if (StringUtils.isNotEmpty(vo.getCityCode())
                                        && detail.getOrgCode().equals(vo.getStoreCode())) {
                                    manDto.setAreaCode(vo.getAreaCode());
                                    manDto.setCityCode(vo.getCityCode());
                                    break;
                                }
                            }
                        }
                    }
                }
			}
		}
		// 重新加入缓存
		addStoreManAttachInfo2Cache(manDto);
		return manDto;

	}

	/**
	 * 比对员工岗位数据,返回岗位信息 功能描述: <br>
	 * 〈功能详细描述〉
	 *
	 * @param menus
	 * @param staffInfo
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private EmpLoginExt getEmpExt(List<AuthMenuInfo> menus, StaffInfo staffInfo) {
		EmpLoginExt detail = null;
		EmpLoginExt empLoginExt;
		String positionId;
		for (AuthMenuInfo item : menus) {
			if (item != null && item.getEmpLoginExt() != null) {
				empLoginExt = item.getEmpLoginExt();
				if (ClerkConstants.DEPUTY_STORE_KEEPER.equals(empLoginExt.getPostionId())) {
					positionId = ClerkConstants.STORE_KEEPER;
				} else {
					positionId = empLoginExt.getPostionId();
				}
				if (StringUtils.isBlank(empLoginExt.getOrgCode())) {
					empLoginExt.setOrgCode("");
				}
				// 只有当工号和门店编码同事匹配的时候才算匹配，同一个门店店员存在可选岗位中存在相同岗位门店不同的情况
				if (staffInfo.getLastPositionId().equals(positionId) && staffInfo.getOrgId().equals(empLoginExt.getOrgId()) && staffInfo.getRoleType().equals(empLoginExt.getRoleType())) {
					detail = empLoginExt;
					detail.setPostionId(positionId);
					break;
				}
			}
		}
		return detail;
	}

	/**
	 * 根据岗位技术品类数据 功能描述: <br>
	 * 〈功能详细描述〉
	 *
	 * @param positionId
	 * @param employeee
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private List<Category> tranferStoreInfo(String positionId, Employee employeee) {
		String categoryCode = employeee.getKindCode();
		if (ClerkConstants.STORE_KEEPER.equals(positionId) || ClerkConstants.DEPUTY_STORE_KEEPER.equals(positionId)) {
			// 店长
			categoryCode = SCMConfigUtil.getConfig("allCateCode");
		}
		// 处理兼品类和全品类的情况
		if (JIAN_CATEGORY.equals(categoryCode)) {
			// 兼品类查看kindRemark字段， 67-数码,电脑
			String categoryCodeTemp = "";
			if (StringUtils.isNotBlank(employeee.getKindRemark())) {
				int length = employeee.getKindRemark().length();
				for (int i = 0; i < length; i++) {
					categoryCodeTemp += employeee.getKindRemark().charAt(i) + ",";
				}
				categoryCode = categoryCodeTemp.substring(0, categoryCodeTemp.length() - 1);
			}
		} else if (QUAN_CATEGORY.equals(categoryCode)) {
			categoryCode = SCMConfigUtil.getConfig("allCateCode");
		}
		List<Category> categories = new ArrayList<Category>();
		if (StringUtils.isNotBlank(categoryCode)) {
			// categoryCode 6,7 categoryName 数码,电脑
			String[] categoryCodeArray = categoryCode.split(",");
			int size = categoryCodeArray.length;
			for (int i = 0; i < size; i++) {
				// 取zookeeper配置，将uuq品类编码转换为OMS订单所用的品类编码
				String omsCategoryCode = SCMConfigUtil.getConfig("hrCateCd_" + categoryCodeArray[i]);
				if (StringUtils.isNotBlank(omsCategoryCode)) {
					// 品类编码对应名称改为从SCM上取
					String cateName = SCMConfigUtil.getConfig("hrCate_" + categoryCodeArray[i]);
					if (StringUtils.isNotBlank(cateName)) {
						categories.add(new Category(omsCategoryCode, cateName));
					} else {
						LOGGER.warn("hrCate_{}, 未取到对应名称", categoryCodeArray[i]);
					}
				}
			}
		}
		return categories;
	}

	@Override
	public StoreManIndexShowData getStoreManIndexShowData(String staffId) {
		LOGGER.info("storemanservice.getStoreManIndexShowData, staffId:{}", staffId);
		// 取缓存数据
		StoreManIndexShowData indexShowData = getIndexDataFromCache(staffId);
		if (null != indexShowData) {
			return indexShowData;
		}
		// 根据工号查询岗位
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		if (ClerkConstants.STORE_KEEPER.equals(storeManDto.getPositionId())) {
			// 店长
			indexShowData = getStoreKeeperIndexData(storeManDto.getStoreCode(), staffId);
		} else if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId())) {
			// 督导
			if (CollectionUtils.isNotEmpty(storeManDto.getCategories())) {
				indexShowData = getGuideIndexData(storeManDto.getStoreCode(), storeManDto.getCategories());
			} else {
				LOGGER.warn("getStoreManIndexShowData, staffId:{}, 督导角色无品类", staffId);
			}
		} else {
			// 其他都按店员逻辑处理
			indexShowData = getClerkIndexData(staffId, storeManDto.getStoreCode());
		}
		// 将新增的数据置入缓存中
		setIndexDataCache(indexShowData, staffId);
		return indexShowData;
	}

	/**
	 * 
	 * 功能描述: 取店员首页缓存数据<br>
	 * 〈功能详细描述〉
	 *
	 * @param staffId
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private StoreManIndexShowData getIndexDataFromCache(String staffId) {
		StoreManIndexShowData indexShowData = null;
		// 首页KEY
		final String key = STORE_MAN_INDEX_PREFIX + staffId;
		String json = jedisClient.execute(new JedisAction<String>() {
			@Override
			public String doAction(Jedis jedis) {
				return jedis.get(key);
			}
		});
		if (StringUtils.isNotBlank(json)) {
			indexShowData = GsonUtils.fromJson(json, StoreManIndexShowData.class);
		}
		return indexShowData;
	}

	/**
	 * 
	 * 功能描述: 设置首页数据到缓存里面<br>
	 * 〈功能详细描述〉
	 *
	 * @param indexShowData
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private void setIndexDataCache(StoreManIndexShowData indexShowData, String staffId) {
		if (null == indexShowData) {
			return;
		}
		final String json = GsonUtils.toJson(indexShowData, false);
		final String key = STORE_MAN_INDEX_PREFIX + staffId;
		String zookeeperTime = ConfigUtil.getConfig("/config/sawp/config", "indexDataCacheExpireTime");
		final int seconds = NumberUtils.isNumber(zookeeperTime) ? Integer.parseInt(zookeeperTime) : STORE_MAN_INDEX_EXPIRE_TIME;

		jedisClient.execute(new JedisAction<String>() {
			@Override
			public String doAction(Jedis jedis) {
				jedis.setex(key, seconds, json);
				return null;
			}
		});
	}

	/**
	 * 
	 * 功能描述: 组装店长的首页展示数据<br>
	 * 〈功能详细描述〉
	 *
	 * @param storeCode
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private StoreManIndexShowData getStoreKeeperIndexData(String storeCode, String staffId) {
		StoreManIndexShowData indexShowData = new StoreManIndexShowData();
		// 查询门店当前销售额，截止至昨天的当月销售额数据+今日的准实时数据
		// 当月销售额
		BIStoreSaleAllMonth saleAllMonth = biSaleAmountDaoService.queryStoreSaleAllMonthByStoreCode(storeCode, DateUtils.getThisMonth());
		// 查询当日销售额
		BIStoreSaleAllDay saleAllDay = biSaleAmountDaoService.queryStoreSaleAllDayByStoreCode(storeCode, DateUtils.getDateStrByFormat(new Date(), DateUtils.YYYYMMDD_PATTERN));
		double thisMonthSaleAmount = 0.0;
		Integer rank = null;
		BigDecimal custAvgPrice = null;
		// 不再显示环比，暂时注释掉，以防后面再用
		BigDecimal custAvgPriceYoy = null;
		BigDecimal saleYoy = null;
		if (null != saleAllMonth) {
			thisMonthSaleAmount += (null != saleAllMonth.getSaleAmount() ? saleAllMonth.getSaleAmount().doubleValue() : 0.0);
			rank = saleAllMonth.getRanking();
			custAvgPrice = saleAllMonth.getCustAvgPrice();
			custAvgPriceYoy = getYoy(saleAllMonth.getLastYearCustAvgPrice(), saleAllMonth.getCustAvgPrice());
			saleYoy = getYoy(saleAllMonth.getLastYearSaleAmount(), saleAllMonth.getSaleAmount());
		}
		if (null != saleAllDay) {
			thisMonthSaleAmount += (null != saleAllDay.getSaleAmount() ? saleAllDay.getSaleAmount().doubleValue() : 0.0);
		}
		// 当月准实时销售额
		// 门店排名，取截止到昨天的当月排名即可
		IndexCateSaleDto cateSale = new IndexCateSaleDto(DJStringUtils.setDecimal(thisMonthSaleAmount), rank);
		// 客单价
		cateSale.setCustAvgPrice(custAvgPrice);
		// 客单价同比
		cateSale.setCustAvgPriceYoy(custAvgPriceYoy);
		// 销售同比
		cateSale.setSaleYoy(saleYoy);
		List<IndexCateSaleDto> cateSales = new ArrayList<IndexCateSaleDto>();
		cateSales.add(cateSale);
		indexShowData.setCateSales(cateSales);
		// 取任务门店列表
		// 查询门店进行中任务列表
		/*
		 * 新主推上线，此处老主推不再使用，屏蔽 List<StoreManTask> tasks =
		 * taskStoreAndClerkDaoService.queryProcessingStoreTasks(storeCode,
		 * null); // 取任务编号集合 if (CollectionUtils.isNotEmpty(tasks)) { Set<Long>
		 * taskNos = new HashSet<Long>(); Set<Long> hasGuideTaskNos = new
		 * HashSet<Long>(); for (StoreManTask taskStore : tasks) { //
		 * 没有挂靠督导的品类，店长才可以分配 if
		 * (storeManRemoteService.validHasGuideByCateCode(storeCode, staffId,
		 * taskStore.getCategoryCode())) {
		 * hasGuideTaskNos.add(taskStore.getTaskNo()); //
		 * 该品类下有督导，店长只能查看详情,置为已分配状态
		 * taskStore.setTaskAssignStatus(Integer.valueOf
		 * (MainPushTask.AssignStatusConstants.ASSIGNED)); }
		 * taskNos.add(taskStore.getTaskNo()); } // 查询任务下未分配商品数量
		 * List<TaskCommStatistic> statistics =
		 * biSaleAmountDaoService.queryTaskCommNoAssigns(taskNos);
		 * List<StoreManTask> removeList = new ArrayList<StoreManTask>(); for
		 * (StoreManTask taskStore : tasks) { for (TaskCommStatistic statistic :
		 * statistics) { if
		 * (statistic.getTaskNo().equals(taskStore.getTaskNo())) { //
		 * 有挂靠督导的品类任务，待分配商品数量为0 if
		 * (!hasGuideTaskNos.contains(taskStore.getTaskNo())) {
		 * taskStore.setAssignProductNum(statistic.getSum()); }
		 * taskStore.setDestNum(statistic.getTotalDestNum()); } } //
		 * 目标台数为null或者为0的任务不展示在首页 if (null == taskStore.getDestNum() ||
		 * taskStore.getDestNum() < 1) { removeList.add(taskStore); } }
		 * 
		 * // 剔除掉目标台数为0的任务 tasks.removeAll(removeList); }
		 * Collections.sort(tasks); indexShowData.setTasks(tasks);
		 */
		return indexShowData;
	}

	/**
	 * 
	 * 功能描述: 计算环比<br>
	 * 〈功能详细描述〉
	 *
	 * @param lastData
	 * @param currentData
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private BigDecimal getMom(BigDecimal lastData, BigDecimal currentData) {
		if (null != lastData && null != currentData && ZERO.compareTo(lastData) != 0) {
			return currentData.divide(lastData, 3, RoundingMode.HALF_UP).subtract(new BigDecimal(1));
		}
		return null;
	}

	/**
	 * 
	 * 功能描述: 计算同比<br>
	 * 〈功能详细描述〉
	 *
	 * @param lastData
	 * @param currentData
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private BigDecimal getYoy(BigDecimal lastData, BigDecimal currentData) {
		if (null != lastData && null != currentData && ZERO.compareTo(lastData) != 0) {
			return currentData.divide(lastData, 3, RoundingMode.HALF_UP).subtract(new BigDecimal(1));
		}
		return null;
	}

	/**
	 * 
	 * 功能描述: 获取督导首页数据<br>
	 * 〈功能详细描述〉
	 *
	 * @param storeCode
	 * @param staffId
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private StoreManIndexShowData getGuideIndexData(String storeCode, List<Category> categories) {
		StoreManIndexShowData indexShowData = new StoreManIndexShowData();
		// 查询督导所属品类的实时销售额，截止到昨天的当月销售额
		// 店员所属品类
		List<IndexCateSaleDto> cateSales = new ArrayList<IndexCateSaleDto>();
		Set<String> categoryCodes = new HashSet<String>();
		Map<String, String> cateMap = new HashMap<String, String>();
		for (Category category : categories) {
			categoryCodes.add(category.getCategoryCode());
			cateMap.put(category.getCategoryCode(), category.getCategoryName());
			IndexCateSaleDto cateSaleDto = new IndexCateSaleDto("0.00", category.getCategoryCode(), category.getCategoryName());
			cateSales.add(cateSaleDto);
		}
		// 截止到昨天的当月销售额
		List<BIStoreSaleCateMonth> saleAmountMonths = biSaleAmountDaoService.queryStoreCateSaleAmountMonth(storeCode, categoryCodes, DateUtils.getThisMonth());
		// 销售额
		for (BIStoreSaleCateMonth cateMonth : saleAmountMonths) {
			for (IndexCateSaleDto dto : cateSales) {
				if (dto.getCategoryCode().equals(cateMonth.getCateCode())) {
					double amount = Double.valueOf(dto.getThisMonthSaleAmount()) + (null != cateMonth.getSaleAmount() ? cateMonth.getSaleAmount().doubleValue() : 0.0);
					dto.setThisMonthSaleAmount(DJStringUtils.setDecimal(amount));
					dto.setRank(cateMonth.getRanking());
					// 客单价
					dto.setCustAvgPrice(cateMonth.getCustAvgPrice());
					// 客单价环比
					dto.setCustAvgPriceMom(getMom(cateMonth.getLastMonthCustAvgPrice(), cateMonth.getCustAvgPrice()));
					// 销售环比
					dto.setSaleMom(getMom(cateMonth.getLastMonthSaleAmount(), cateMonth.getSaleAmount()));
					// 客单价同比
					dto.setCustAvgPriceYoy(getYoy(cateMonth.getLastYearCustAvgPrice(), cateMonth.getCustAvgPrice()));
					// 销售同比
					dto.setSaleYoy(getYoy(cateMonth.getLastYearSaleAmount(), cateMonth.getSaleAmount()));
				}
			}
		}
		// 今日准实时销售额
		List<BIStoreSaleCateDay> saleAmountDays = biSaleAmountDaoService.queryStoreCateSaleAmountDay(storeCode, categoryCodes, DateUtils.getDateStrByFormat(new Date(), DateUtils.YYYYMMDD_PATTERN));
		for (BIStoreSaleCateDay cateDay : saleAmountDays) {
			for (IndexCateSaleDto dto : cateSales) {
				if (dto.getCategoryCode().equals(cateDay.getCateCode())) {
					double amount = Double.valueOf(dto.getThisMonthSaleAmount()) + (null != cateDay.getSaleAmount() ? cateDay.getSaleAmount().doubleValue() : 0.0);
					dto.setThisMonthSaleAmount(DJStringUtils.setDecimal(amount));
				}
			}
		}
		indexShowData.setCateSales(cateSales);
		// 门店督导所属品类进行中主推任务
		/*
		 * 新主推上线，老主推不再使用，屏蔽 List<StoreManTask> tasks =
		 * taskStoreAndClerkDaoService.queryProcessingStoreTasks(storeCode,
		 * categoryCodes); // 取任务编号集合 if (CollectionUtils.isNotEmpty(tasks)) {
		 * Set<Long> taskNos = new HashSet<Long>(); for (StoreManTask taskStore
		 * : tasks) { taskNos.add(taskStore.getTaskNo()); } // 查询任务下未分配商品数量
		 * List<TaskCommStatistic> statistics =
		 * biSaleAmountDaoService.queryTaskCommNoAssigns(taskNos);
		 * List<StoreManTask> removeList = new ArrayList<StoreManTask>(); for
		 * (StoreManTask taskStore : tasks) { for (TaskCommStatistic statistic :
		 * statistics) { if
		 * (statistic.getTaskNo().equals(taskStore.getTaskNo())) {
		 * taskStore.setAssignProductNum(statistic.getSum());
		 * taskStore.setDestNum(statistic.getTotalDestNum()); } } //
		 * 目标台数为null或者为0的任务不展示在首页 if (null == taskStore.getDestNum() ||
		 * taskStore.getDestNum() < 1) { removeList.add(taskStore); } } //
		 * 剔除掉目标台数为0的任务 tasks.removeAll(removeList); }
		 * 
		 * indexShowData.setTasks(tasks);
		 */

		return indexShowData;
	}

	/**
	 * 
	 * 功能描述: 店员首页数据展示<br>
	 * 〈功能详细描述〉
	 *
	 * @param staffId
	 * @return
	 * @see [相关类/方法](可选)
	 * @since [产品/模块版本](可选)
	 */
	private StoreManIndexShowData getClerkIndexData(String staffId, String storeCode) {
		StoreManIndexShowData indexShowData = new StoreManIndexShowData();
		List<IndexCateSaleDto> cateSales = new ArrayList<IndexCateSaleDto>();
		IndexCateSaleDto cateSaleDto = new IndexCateSaleDto();
		// 店员销售额 截止至昨日的当月销售额 + 今日准实时销售额
		// 当月销售额
		BIStaffSaleAllMonth saleAllMonth = biSaleAmountDaoService.queryStaffSaleAllMonthByStaffId(staffId);
		// 今日准实时
		BIStaffSaleAllDay saleAllDay = biSaleAmountDaoService.queryStaffSaleAllDayByStaffId(staffId);
		double saleAmount = 0.0;
		if (null != saleAllMonth) {
			saleAmount += (null != saleAllMonth.getSaleAmount() ? saleAllMonth.getSaleAmount().doubleValue() : 0.0);
			// 排名
			cateSaleDto.setRank(saleAllMonth.getRanking());
		}
		if (null != saleAllDay) {
			saleAmount += (null != saleAllDay.getSaleAmount() ? saleAllDay.getSaleAmount().doubleValue() : 0.0);
		}
		cateSaleDto.setThisMonthSaleAmount(DJStringUtils.setDecimal(saleAmount));
		// 个人当月提成
		StoreManRealIncSum income = biDataDaoService.queryTotalIncomeInfo(staffId);
		if (null != income) {
			if (null != income.getTotIncome()) {
				cateSaleDto.setCommssionAmount(DJStringUtils.setDecimal(income.getTotIncome().doubleValue()));
			} else {
				cateSaleDto.setCommssionAmount("0.00");
			}
		}
		cateSales.add(cateSaleDto);
		indexShowData.setCateSales(cateSales);
		// 查询店员主推任务
		/*
		 * 新主推上线，老主推不再使用，屏蔽 List<StoreManTask> storeManTasks = new
		 * ArrayList<StoreManTask>(); List<TaskClerk> tasks =
		 * taskStoreAndClerkDaoService.queryProcessingStaffTasks(staffId); if
		 * (CollectionUtils.isNotEmpty(tasks)) { Set<Long> storeTaskNos = new
		 * HashSet<Long>(); Map<Long, TaskClerk> map = new HashMap<Long,
		 * TaskClerk>(); Map<Long, TaskCommStatistic> products = new
		 * HashMap<Long, TaskCommStatistic>(); for (TaskClerk taskClerk : tasks)
		 * { storeTaskNos.add(taskClerk.getParTaskNo());
		 * map.put(taskClerk.getParTaskNo(), taskClerk); // 主推任务所属商品编码
		 * TaskCommStatistic gds =
		 * taskStoreAndClerkDaoService.getGoodsCodesInTaskClerk
		 * (taskClerk.getTaskNo()); products.put(taskClerk.getParTaskNo(), gds);
		 * } // 根据大区主推任务任务编号查询总部任务编码 List<TaskNoDto> hqAndStoreTaskNos =
		 * taskStoreAndClerkDaoService.queryHqTaskNosByClerk(storeTaskNos);
		 * List<Long> hqTaskNos = new ArrayList<Long>(); for (TaskNoDto dto :
		 * hqAndStoreTaskNos) { hqTaskNos.add(dto.getHqTaskNo());
		 * map.put(dto.getHqTaskNo(), map.get(dto.getStoreTaskNo()));
		 * products.put(dto.getHqTaskNo(), products.get(dto.getStoreTaskNo()));
		 * map.remove(dto.getStoreTaskNo());
		 * products.remove(dto.getStoreTaskNo()); } // 查找对应的店员主推任务BI统计
		 * List<StoreManTask> biTasks =
		 * taskStoreAndClerkDaoService.queryBiClerkMainpushTasks(staffId,
		 * storeCode, hqTaskNos);
		 * 
		 * Set<Entry<Long, TaskClerk>> entries = map.entrySet(); for
		 * (Entry<Long, TaskClerk> entry : entries) { // 查询主推任务的提成信息 //
		 * 商品编码集及商品目标台数 TaskCommStatistic gds = products.get(entry.getKey());
		 * TaskClerk taskClerk = entry.getValue(); StoreManTask manTask = new
		 * StoreManTask(); // 取对应的主推任务商品提成 BigDecimal actMount =
		 * biDataDaoService.getStoreManMainPushActAmount(staffId,
		 * taskClerk.getStartTime(), taskClerk.getEndTime(),
		 * gds.getGoodsCode());
		 * manTask.setCategoryCode(taskClerk.getCategoryCode());
		 * manTask.setCategoryName(taskClerk.getCategoryName());
		 * manTask.setDestNum(gds.getSum()); manTask.setTaskCommssionAmount(null
		 * == actMount ? new BigDecimal("0.00") : actMount);
		 * manTask.setTaskType(taskClerk.getTaskType());
		 * manTask.setTaskNo(taskClerk.getTaskNo()); // 店员的任务分配状态都为详情
		 * manTask.setTaskAssignStatus
		 * (Integer.valueOf(MainPushTask.AssignStatusConstants.ASSIGNED)); for
		 * (StoreManTask task : biTasks) { if
		 * (entry.getKey().equals(task.getTaskNo())) { // 主推任务销售额
		 * manTask.setTaskSaleAmount(task.getTaskSaleAmount());
		 * manTask.setCompleteNum(task.getCompleteNum());
		 * manTask.setTaskRank(task.getTaskRank());
		 * manTask.setRankTrend(task.getRankTrend()); } }
		 * storeManTasks.add(manTask); } }
		 * indexShowData.setTasks(storeManTasks);
		 */

		return indexShowData;
	}

	@Override
	public void removeIndexShowDataCache(String staffId) {
		// 删除首页缓存
		final String key = STORE_MAN_INDEX_PREFIX + staffId;
		jedisClient.execute(new JedisAction<Long>() {
			@Override
			public Long doAction(Jedis jedis) {
				return jedis.del(key);
			}
		});
	}

	@Override
	public List<RankingListDto> getHeroListData(String staffId, String categoryCode) {
		// 根据工号查询岗位
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		List<RankingListDto> list = new ArrayList<RankingListDto>();
		if (ClerkConstants.STORE_KEEPER.equals(storeManDto.getPositionId())) {
			// 店长
			List<BIStoreSaleAllMonth> saleAllMonths = biSaleAmountDaoService.querySaleSortStoreByRegCd(storeManDto.getRegionCode(), 10);
			int size = saleAllMonths.size();
			for (int i = 0; i < size; i++) {
				BIStoreSaleAllMonth sale = saleAllMonths.get(i);
				RankingListDto dto = new RankingListDto();
				dto.setRank(i + 1);
				dto.setStoreCode(sale.getStoreCode());
				dto.setStoreName(sale.getStoreName());
				dto.setCompleteRate(sale.getSaleCompleteRate());
				if (i > 0) {
					RankingListDto lastDto = list.get(i - 1);
					if (lastDto.getCompleteRate().equals(dto.getCompleteRate())) {
						dto.setRank(lastDto.getRank());
					}
				}
				list.add(dto);
			}
		} else if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId())) {
			// 督导
			// 查询门店品类的英雄榜
			List<GuideRankShowDto> guideHeroShowDtos = biSaleAmountDaoService.querySaleCateSortStoreByRegcd(storeManDto.getRegionCode(), categoryCode, 10);
			int size = guideHeroShowDtos.size();
			for (int i = 0; i < size; i++) {
				GuideRankShowDto sale = guideHeroShowDtos.get(i);
				RankingListDto dto = new RankingListDto();
				dto.setRank(i + 1);
				dto.setStoreCode(sale.getStoreCode());
				dto.setStoreName(sale.getStoreName());
				dto.setSaleAmount(sale.getSaleAmount());
				if (i > 0) {
					RankingListDto lastDto = list.get(i - 1);
					if (lastDto.getSaleAmount().equals(dto.getSaleAmount())) {
						dto.setRank(lastDto.getRank());
					}
				}
				list.add(dto);
			}

		} else {
			// 其他都按店员逻辑处理
			// 查询门店店员销售排名
			List<BIStaffSaleAllMonth> staffSaleAllMonths = biSaleAmountDaoService.queryStaffSaleByStoreCode(storeManDto.getStoreCode(), 10);
			int size = staffSaleAllMonths.size();
			for (int i = 0; i < size; i++) {
				BIStaffSaleAllMonth sale = staffSaleAllMonths.get(i);
				RankingListDto dto = new RankingListDto();
				dto.setRank(i + 1);
				dto.setStaffId(sale.getStaffId());
				dto.setStaffName(sale.getStaffName());
				dto.setSaleAmount(sale.getSaleAmount());
				if (i > 0) {
					RankingListDto lastDto = list.get(i - 1);
					if (lastDto.getSaleAmount().equals(dto.getSaleAmount())) {
						dto.setRank(lastDto.getRank());
					}
				}
				list.add(dto);
			}
		}

		return list;
	}

	@Override
	public List<SaleStatisticDto> getSaleStatistic(String staffId) {
		List<SaleStatisticDto> list = new ArrayList<SaleStatisticDto>();
		// 根据工号查询岗位
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		String thisMonth = DateUtils.getThisMonth();
		String month = String.valueOf(DateUtils.getMonOfDate(new Date()));
		String today = DateUtils.getDateStrByFormat(new Date(), DateUtils.YYYYMMDD_PATTERN);
		String yesterday = DateUtils.getDateStrByFormat(DateUtils.getNextDay(new Date(), -1), DateUtils.YYYYMMDD_PATTERN);
		if (ClerkConstants.STORE_KEEPER.equals(storeManDto.getPositionId())) {
			// 店长
			// 本月销售额
			BIStoreSaleAllMonth saleAllMonth = biSaleAmountDaoService.queryStoreSaleAllMonthByStoreCode(storeManDto.getStoreCode(), thisMonth);
			// 今日销售额
			BIStoreSaleAllDay todaySale = biSaleAmountDaoService.queryStoreSaleAllDayByStoreCode(storeManDto.getStoreCode(), today);
			// 昨日销售额
			BIStoreSaleAllDay yestdSale = biSaleAmountDaoService.queryStoreSaleAllDayByStoreCode(storeManDto.getStoreCode(), yesterday);
			BigDecimal thisMonthSaleAmount = null == saleAllMonth ? new BigDecimal("0.00") : saleAllMonth.getSaleAmount();
			BigDecimal todaySaleAmount = (null == todaySale || null == todaySale.getSaleAmount()) ? new BigDecimal("0.00") : todaySale.getSaleAmount();
			BigDecimal yestdSaleAmount = (null == yestdSale || null == yestdSale.getSaleAmount()) ? new BigDecimal("0.00") : yestdSale.getSaleAmount();
			SaleStatisticDto statisticDto = new SaleStatisticDto(thisMonthSaleAmount.add(todaySaleAmount), todaySaleAmount, yestdSaleAmount);
			// 增加销售完成率
			statisticDto.setCompleteRate(null != saleAllMonth ? saleAllMonth.getSaleCompleteRate() : null);
			// 月度任务销售额
			statisticDto.setTaskSaleAmount(null != saleAllMonth ? saleAllMonth.getTaskSaleAmount() : null);
			// 月度任务毛利额
			statisticDto.setTaskGrossProfit(null != saleAllMonth ? saleAllMonth.getTaskGrossProfit() : null);
			// 当前月份
			statisticDto.setMonth(month);
			list.add(statisticDto);
		} else if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId())) {
			// 督导
			Set<String> categoryCodes = new HashSet<String>();
			Map<String, String> cateMap = new HashMap<String, String>();
			for (Category category : storeManDto.getCategories()) {
				categoryCodes.add(category.getCategoryCode());
				cateMap.put(category.getCategoryCode(), category.getCategoryName());
			}
			// 本月该品类销售额
			List<BIStoreSaleCateMonth> monthSales = biSaleAmountDaoService.queryStoreCateSaleAmountMonth(storeManDto.getStoreCode(), categoryCodes, thisMonth);
			// 今日该品类销售额
			List<BIStoreSaleCateDay> todaySales = biSaleAmountDaoService.queryStoreCateSaleAmountDay(storeManDto.getStoreCode(), categoryCodes, today);
			// 昨日该品类销售额
			List<BIStoreSaleCateDay> yestdSales = biSaleAmountDaoService.queryStoreCateSaleAmountDay(storeManDto.getStoreCode(), categoryCodes, yesterday);

			for (BIStoreSaleCateMonth saleCateMonth : monthSales) {
				SaleStatisticDto statisticDto = new SaleStatisticDto();
				statisticDto.setCategoryCode(saleCateMonth.getCateCode());
				statisticDto.setCategoryName(cateMap.get(saleCateMonth.getCateCode()));
				double thisMonthSaleAmount = saleCateMonth.getSaleAmount().doubleValue();
				for (BIStoreSaleCateDay cateDay : todaySales) {
					if (saleCateMonth.getCateCode().equals(cateDay.getCateCode())) {
						// 品类相同，取今日销售额
						thisMonthSaleAmount += cateDay.getSaleAmount().doubleValue();
						statisticDto.setTodaySaleAmount(cateDay.getSaleAmount());
					}
				}
				statisticDto.setThisMonSaleAmount(BigDecimal.valueOf(thisMonthSaleAmount));
				// 昨日销售额
				for (BIStoreSaleCateDay yestDay : yestdSales) {
					if (saleCateMonth.getCateCode().equals(yestDay.getCateCode())) {
						statisticDto.setYestdSaleAmount(yestDay.getSaleAmount());
					}
				}
				// 月度任务销售额
				statisticDto.setTaskSaleAmount(saleCateMonth.getTaskSaleAmount());
				// 月度任务毛利额
				statisticDto.setTaskGrossProfit(saleCateMonth.getTaskGrossProfit());
				// 销售完成率
				statisticDto.setCompleteRate(DJStringUtils.calculateRate(saleCateMonth.getSaleAmount(), saleCateMonth.getTaskSaleAmount()));
				// 当前月份
				statisticDto.setMonth(month);
				list.add(statisticDto);
			}
		}
		return list;
	}

	@Override
	public List<StoreCateSaleStatis> getStoreCateSalestatis(String staffId, String categoryCode, int sort, String sortType, int startIndex, int limit) {
		List<StoreCateSaleStatis> cateSaleStatis = null;
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		if (ClerkConstants.STORE_KEEPER.equals(storeManDto.getPositionId())) {
			// 店长
			cateSaleStatis = biSaleAmountDaoService.queryStoreCateSaleStatis(categoryCode, storeManDto.getStoreCode(), sort);
			// 补充品类名称
			for (StoreCateSaleStatis saleStatis : cateSaleStatis) {
				String categoryName = ConfigUtil.getConfig(ConfigConstants.SAWP_CONFIG_MAIN_PUSH_CATEGORY, saleStatis.getCategoryCode());
				saleStatis.setCategoryName(categoryName);
			}
		} else if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId())) {
			// 督导
			cateSaleStatis = biSaleAmountDaoService.queryStoreCateDaySale(categoryCode, storeManDto.getStoreCode(), startIndex, limit, sort, sortType);
		}
		return cateSaleStatis;
	}

	@Override
	public void saveLastestChooseMan(String staffId, LastestChooseManReqDto chooseManReqDto) {
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		lastestChooseManService.saveLastestChooseMans(storeManDto.getStoreCode(), chooseManReqDto.getCategoryCode(), chooseManReqDto.getStoreMans());
	}

	@Override
	public List<RankingListDto> getMainPushRankingList(String staffId, Long taskNo) {
		List<RankingListDto> list = new ArrayList<RankingListDto>();
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		if (ClerkConstants.STORE_KEEPER.equals(storeManDto.getPositionId())) {
			Long hqTaskNo = taskStoreAndClerkDaoService.queryHqTaskNo(taskNo, MainPushTask.OrgLevelConstants.LEVEL_STORE);
			// 店长
			List<RankingListDto> taskMonths = biSaleAmountDaoService.queryStoreMainPushRankingList(storeManDto.getRegionCode(), hqTaskNo);
			int size = taskMonths.size();
			for (int i = 0; i < size; i++) {
				RankingListDto sale = taskMonths.get(i);
				RankingListDto dto = new RankingListDto();
				dto.setRank(i + 1);
				dto.setStoreCode(sale.getStoreCode());
				dto.setStoreName(sale.getStoreName());
				dto.setCompleteRate(sale.getCompleteRate());
				if (i > 0) {
					RankingListDto lastDto = list.get(i - 1);
					if (lastDto.getCompleteRate().equals(dto.getCompleteRate())) {
						dto.setRank(lastDto.getRank());
					}
				}
				list.add(dto);
			}
		} else if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId())) {
			// 督导
			Long hqTaskNo = taskStoreAndClerkDaoService.queryHqTaskNo(taskNo, MainPushTask.OrgLevelConstants.LEVEL_STORE);
			List<GuideRankShowDto> taskMonths = biSaleAmountDaoService.queryStoreGuideMainPushRankingList(storeManDto.getRegionCode(), hqTaskNo);
			int size = taskMonths.size();
			for (int i = 0; i < size; i++) {
				GuideRankShowDto sale = taskMonths.get(i);
				RankingListDto dto = new RankingListDto();
				dto.setRank(i + 1);
				dto.setStoreCode(sale.getStoreCode());
				dto.setStoreName(sale.getStoreName());
				dto.setCompleteRate(sale.getCompleteRate());
				if (i > 0) {
					RankingListDto lastDto = list.get(i - 1);
					if (lastDto.getCompleteRate().equals(dto.getCompleteRate())) {
						dto.setRank(lastDto.getRank());
					}
				}
				list.add(dto);
			}
		} else {
			// 店员
			Long hqTaskNo = taskStoreAndClerkDaoService.queryHqTaskNo(taskNo, MainPushTask.OrgLevelConstants.LEVEL_CLERK);
			List<BIStaffPushTaskMonth> taskMonths = biSaleAmountDaoService.queryStoreStaffMainPushRankingList(storeManDto.getStoreCode(), hqTaskNo);
			int size = taskMonths.size();
			for (int i = 0; i < size; i++) {
				BIStaffPushTaskMonth sale = taskMonths.get(i);
				RankingListDto dto = new RankingListDto();
				dto.setRank(i + 1);
				dto.setStaffId(sale.getStaffId());
				dto.setStaffName(sale.getStaffName());
				dto.setSaleVolume(sale.getSaleVolume());
				if (i > 0) {
					RankingListDto lastDto = list.get(i - 1);
					if (lastDto.getSaleVolume() == dto.getSaleVolume()) {
						dto.setRank(lastDto.getRank());
					}
				}
				list.add(dto);
			}
		}
		return list;
	}

	@Override
	public BIStoreTask getStoreMainPushDetail(String staffId, Long taskNo, String categoryCode) {
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		if (ClerkConstants.STORE_KEEPER.equals(storeManDto.getPositionId()) || ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId())) {
			// 店长和督导
			TaskStoreTempDto taskStore = null;
			if (null != taskNo) {
				taskStore = storeTaskBIShowService.queryTaskStoreByTaskNo(taskNo);
			} else {
				taskStore = storeTaskBIShowService.queryActiveTaskByCateCode(categoryCode, storeManDto.getStoreCode());
			}

			if (null != taskStore) {
				return storeTaskBIShowService.queryStoreTask(taskStore);
			}
		} else {
			// 店员
			// 根据工号和品类编码查询店员任务编号
			TaskClerk taskClerk = taskStoreAndClerkDaoService.queryClerkTaskByTaskNo(taskNo);
			// 根据店员任务编号查找所属商品
			return storeTaskBIShowService.queryClerkTask(taskClerk, staffId);
		}
		return null;
	}

	@Override
	public StoreTaskCompleteDto getStoreTaskCompleteDetail(String staffId, Long storeTaskNo, String uniCode, String saleDate, String queryType) {
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		StoreTaskCompleteDto completeDto = new StoreTaskCompleteDto();
		List<StoreTaskCompleteDetail> details = new ArrayList<StoreTaskCompleteDetail>();
		// saleDate为空，按人员查，不区分日期查询
		Long hqTaskNo = taskStoreAndClerkDaoService.queryHqTaskNo(storeTaskNo, MainPushTask.OrgLevelConstants.LEVEL_STORE);
		TaskStoreTempDto taskStore = taskStoreAndClerkDaoService.queryTaskStoreByTaskNo(storeTaskNo);
		String startDate = DateUtils.getDateStrByFormat(taskStore.getStartTime(), DateUtils.YYYYMMDD_PATTERN);
		String endDate = DateUtils.getDateStrByFormat(taskStore.getEndTime(), DateUtils.YYYYMMDD_PATTERN);
		String yesterday = DateUtils.getDateStrByFormat(DateUtils.getNextDay(new Date(), -1), DateUtils.YYYYMMDD_PATTERN);
		List<ClerkMainPushSaleComplete> completes = null;
		if ("0".equals(queryType)) {
			completeDto.setStartDate(startDate);
			completeDto.setYesterday(yesterday);
			// 按日期查
			String saleTime = StringUtils.isBlank(saleDate) ? yesterday : saleDate;
			completes = biSaleAmountDaoService.queryClerkMainPushSaleDayCompletes(hqTaskNo, storeManDto.getStoreCode(), saleTime, uniCode);
		} else if ("1".equals(queryType)) {
			// 按人员查
			completes = biSaleAmountDaoService.queryClerkMainPushSaleCompletes(hqTaskNo, storeManDto.getStoreCode(), startDate, endDate, uniCode);
		}
		if (null != completes) {
			for (ClerkMainPushSaleComplete complete : completes) {
				StoreTaskCompleteDetail detail = new StoreTaskCompleteDetail();
				detail.setStaffId(complete.getStaffId());
				detail.setStaffName(complete.getStaffName());
				detail.setSaleVolume(complete.getSaleVolume());
				double proportion = complete.getTotalSaleVolume() == 0 ? 0.0 : (double) complete.getSaleVolume() / complete.getTotalSaleVolume();
				detail.setProportion(BigDecimal.valueOf(proportion).setScale(2, BigDecimal.ROUND_HALF_UP));
				details.add(detail);
			}
		}

		completeDto.setCommStaffs(details);
		return completeDto;
	}

	@Override
	public List<EmployeeInfo> getClerksInStore(String staffId) {
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		// 00010001-营业员 00010002-促销员
		EmpListOfOrgPos orgPos = employeeService.getEmpListOfOrgPos(storeManDto.getStoreCode(), "00010001,00010002");
		if (null != orgPos && NsfuaaResult.SUCCESS == orgPos.getStatus()) {
			return orgPos.getEmpList();
		} else {
			return new ArrayList<EmployeeInfo>();
		}
	}

	@Override
	public List<EmployeeInfo> getClerksInStoreEx(String staffId, String positionIds) {
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		EmpListOfOrgPos orgPos = employeeService.getEmpListOfOrgPos(storeManDto.getStoreCode(), positionIds);
		if (null != orgPos && NsfuaaResult.SUCCESS == orgPos.getStatus()) {
			return orgPos.getEmpList();
		} else {
			return new ArrayList<EmployeeInfo>();
		}
	}

	@Override
	public List<EmployeeInfo> getClerksInStoretiByStoreCd(String storeCode, String positionIds) {
		EmpListOfOrgPos orgPos = employeeService.getEmpListOfOrgPos(storeCode, positionIds);
		if (null != orgPos && NsfuaaResult.SUCCESS == orgPos.getStatus()) {
			return orgPos.getEmpList();
		} else {
			return new ArrayList<EmployeeInfo>();
		}
	}

	public List<EmployeeInfo> getClerksInStoreByStoreCodeAndCateCode(String storeCode, String positionId, String cateCode) {
		String kindCode = ConfigConstants.CATE_KIND_MAP.get(cateCode);
		if (kindCode == null) {
			return new ArrayList<EmployeeInfo>();
		}
		EmpListOfOrgPos orgPos = employeeService.queryEmpListBykindCode(storeCode, positionId, kindCode);
		if (null != orgPos && NsfuaaResult.SUCCESS == orgPos.getStatus()) {
			return orgPos.getEmpList();
		} else {
			return new ArrayList<EmployeeInfo>();
		}
	}

	@Override
	public List<EmployeeInfo> getLastestChooseMans(String staffId, String categoryCode) {
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		return lastestChooseManService.getLastestChooseMans(storeManDto.getStoreCode(), categoryCode);
	}

	@Override
	public ReturnMsg<List<StoreMonSaleDetailDto>> getStoreMonSales(String staffId) {
		ReturnMsg<List<StoreMonSaleDetailDto>> returnMsg = new ReturnMsg<List<StoreMonSaleDetailDto>>();
		LOGGER.info("StoreManService.getStoreMonSales in staffId:{}", staffId);
		// 根据工号查询店员基本信息
		StoreManDto manDto = queryStoreManAttachInfo(staffId);
		if (null != manDto && StringUtils.isNotBlank(manDto.getStoreCode()) && ClerkConstants.STORE_KEEPER.equals(manDto.getPositionId())) {
			List<StoreMonSaleDetailDto> detailDtos = biSaleAmountDaoService.queryStoreMonSaleDetails(manDto.getStoreCode());
			if (CollectionUtils.isNotEmpty(detailDtos)) {
				// YYYYMM转换日期展示格式 YYYY-MM
				for (StoreMonSaleDetailDto dto : detailDtos) {
					if (StringUtils.isNotBlank(dto.getSaleMonth()) && dto.getSaleMonth().length() == 6) {
						String month = dto.getSaleMonth().substring(0, 4) + "-" + dto.getSaleMonth().substring(4, 6);
						dto.setSaleMonth(month);
					}
				}
				returnMsg.setData(detailDtos);
			} else {
				LOGGER.warn("StoreManService.getStoreMonSales query no data staffId:{}", staffId);
			}
		} else {
			// 门店编码不存在
			LOGGER.error("StoreManService.getStoreMonSales staffId:{}, storeCode not exist");
			returnMsg.setError(ErrorCodeConstants.ERR_0001);
		}

		return returnMsg;
	}

	@Override
	public ReturnMsg<BiStoreKeeperSaleDataDto> getStoreKeeperWapSaleData(String staffId) {
		ReturnMsg<BiStoreKeeperSaleDataDto> returnMsg = new ReturnMsg<BiStoreKeeperSaleDataDto>();
		StoreManDto manDto = queryStoreManAttachInfo(staffId);
		if (null != manDto && ClerkConstants.STORE_KEEPER.equals(manDto.getPositionId())) {
			// 判断此用户是否为店长角色，如果不是给予提示
			BiStoreKeeperSaleDataDto dataDto = new BiStoreKeeperSaleDataDto();
			String thisMonth = DateUtils.getThisMonth();
			BIStoreSaleAllMonth saleAllMonth = biSaleAmountDaoService.queryStoreSaleAllMonthByStoreCode(manDto.getStoreCode(), thisMonth);
			if (null != saleAllMonth) {
				// 门店当月任务毛利额
				dataDto.setGrossProfitTask(saleAllMonth.getTaskGrossProfit());
				// 门店当月任务销售额
				dataDto.setSaleAmountTask(saleAllMonth.getTaskSaleAmount());
				// 门店当月销售完成率
				dataDto.setSaleCompleteRate(saleAllMonth.getSaleCompleteRate());
				// 月度同比
				BigDecimal monYoy = getYoy(saleAllMonth.getLastYearSaleAmount(), saleAllMonth.getSaleAmount());
				dataDto.setMonYoy(monYoy);
			}
			// 取门店8个品类的销售完成率
			Set<String> categoryCodes = new HashSet<String>();
			List<BiStoreCateCompleteRate> cateSaleCompleteRates = new ArrayList<BiStoreCateCompleteRate>();
			for (Category category : manDto.getCategories()) {
				categoryCodes.add(category.getCategoryCode());
				BiStoreCateCompleteRate rate = new BiStoreCateCompleteRate();
				rate.setCateCode(category.getCategoryCode());
				rate.setCateName(category.getCategoryName());
				cateSaleCompleteRates.add(rate);
			}
			List<BIStoreSaleCateMonth> monthSales = biSaleAmountDaoService.queryStoreCateSaleAmountMonth(manDto.getStoreCode(), categoryCodes, thisMonth);
			if (CollectionUtils.isNotEmpty(monthSales)) {
				// 计算八个品类的完成率
				for (BIStoreSaleCateMonth cateMonth : monthSales) {
					for (BiStoreCateCompleteRate rate : cateSaleCompleteRates) {
						if (rate.getCateCode().equals(cateMonth.getCateCode())) {
							rate.setCompleteRate(DJStringUtils.calculateRate(cateMonth.getSaleAmount(), cateMonth.getTaskSaleAmount()));
							break;
						}
					}
				}
			}

			dataDto.setCateSaleCompleteRates(cateSaleCompleteRates);

			// 增加今日销售额，同比，排名
			// 根据工号查询对应销售数据-临时方案，后期首页整改时需要
			StoreManIndexShowData indexShowData = getStoreManIndexShowData(staffId);
			if (null != indexShowData && CollectionUtils.isNotEmpty(indexShowData.getCateSales())) {
				// 店长
				List<IndexCateSaleDto> cateSaleDtos = indexShowData.getCateSales();
				// 店长取原先的销售完成率排名
				IndexCateSaleDto saleDto = cateSaleDtos.get(0);
				dataDto.setRank(null != saleDto ? saleDto.getRank() : null);
			}
			// 日实时销售数据
			dataDto.setTodaySaleAmount(biKafkaRealTimeSaleService.queryStoreDaySale(manDto.getStoreCode()));
			// 日实时销售同比
			dataDto.setDaySaleYoy(biKafkaRealTimeSaleService.queryStoreDaySaleYoy(manDto.getStoreCode()));

			returnMsg.setData(dataDto);
		} else {
			LOGGER.warn("getStoreKeeperWapSaleData staffId:{}, no store keeper");
			returnMsg.setError(ErrorCodeConstants.ERR_0035);
		}
		return returnMsg;
	}

	@Override
	public StoreManIndexShowData getStoreManIndexShowDataNew(String staffId) {
		// 根据工号查询对应销售数据-临时方案，后期首页整改时需要
		StoreManIndexShowData indexShowData = getStoreManIndexShowData(staffId);
		List<StoreRealTimeSale> realTimeSales = new ArrayList<StoreRealTimeSale>();
		// 根据工号查询岗位
		StoreManDto storeManDto = queryStoreManAttachInfo(staffId);
		String statisWapUrl = "";
		if (indexShowData != null) {
			try {
				if (ClerkConstants.STORE_KEEPER.equals(storeManDto.getPositionId())) {
					// 店长
					List<IndexCateSaleDto> cateSaleDtos = indexShowData.getCateSales();
					// 店长取原先的销售完成率排名
					IndexCateSaleDto saleDto = cateSaleDtos.get(0);
					StoreRealTimeSale realTimeSale = new StoreRealTimeSale();
					realTimeSale.setRank(null != saleDto ? saleDto.getRank() : null);
					// 日实时销售数据
					realTimeSale.setTodaySaleAmount(biKafkaRealTimeSaleService.queryStoreDaySale(storeManDto.getStoreCode()));
					// 日实时销售同比
					realTimeSale.setDaySaleYoy(biKafkaRealTimeSaleService.queryStoreDaySaleYoy(storeManDto.getStoreCode()));
					// 门店销售详情wap页面
					realTimeSale.setSaleStatisUrl(SCMConfigUtil.getConfig(ConfigConstants.STORE_SALE_STATIS_URL));
					realTimeSales.add(realTimeSale);
				} else if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId())) {
					// 督导
					List<IndexCateSaleDto> cateSaleDtos = indexShowData.getCateSales();
					for (IndexCateSaleDto saleDto : cateSaleDtos) {
						StoreRealTimeSale realTimeSale = new StoreRealTimeSale();
						// 取原有销售完成率排名
						realTimeSale.setRank(null != saleDto ? saleDto.getRank() : null);
						realTimeSale.setCategoryCode(saleDto.getCategoryCode());
						realTimeSale.setCategoryName(saleDto.getCategoryName());
						// 日实时销售数据
						realTimeSale.setTodaySaleAmount(biKafkaRealTimeSaleService.queryStoreCateDaySale(storeManDto.getStoreCode(), saleDto.getCategoryCode()));
						// 日实时销售同比
						realTimeSale.setDaySaleYoy(biKafkaRealTimeSaleService.queryStoreCateDaySaleYoy(storeManDto.getStoreCode(), saleDto.getCategoryCode()));
						realTimeSales.add(realTimeSale);
					}
				} else {
					// 店员
					List<IndexCateSaleDto> cateSaleDtos = indexShowData.getCateSales();
					// 取原先的月度销售、排名、提成
					IndexCateSaleDto saleDto = cateSaleDtos.get(0);
					if (null != saleDto) {
						StoreRealTimeSale realTimeSale = new StoreRealTimeSale();
						realTimeSale.setCommssionAmount(saleDto.getCommssionAmount());
						realTimeSale.setRank(saleDto.getRank());
						realTimeSale.setThisMonthSaleAmount(new BigDecimal(saleDto.getThisMonthSaleAmount()));
						realTimeSales.add(realTimeSale);
					}
				}
			} catch (Exception e) {
				LOGGER.error("getStoreManIndexShowDataNew error.staffId:{}", staffId, e);
			}
		} else {
			indexShowData = new StoreManIndexShowData();
		}

		// 取BI销售数据失败不能影响销售数据wap页面的展示
		// 时光机url
		indexShowData.setTimemachineUrl(SCMConfigUtil.getConfig(ConfigConstants.TIME_MACHINE_URL));
		// 时光机图片URL
		indexShowData.setTimemachineImgurl(SCMConfigUtil.getConfig(ConfigConstants.TIME_MACHINE_IMG_URL));
		if (ClerkConstants.STORE_KEEPER.equals(storeManDto.getPositionId())) {
			if (FAST_SALE_STORE_TYPE.contains(storeManDto.getStoreTypeCode())) {
				// 红孩子，超市，小店的督导，走这个分支，跳转卡单页面
				statisWapUrl = SCMConfigUtil.getConfig(ConfigConstants.FAST_S_EXP_ORDER_IDX_URL);
			} else {
				// 非快销店长数据首页
				statisWapUrl = SCMConfigUtil.getConfig(ConfigConstants.STORE_KEEPER_STATIS_URL);
			}
		} else if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId())) {
			if (FAST_SALE_STORE_TYPE.contains(storeManDto.getStoreTypeCode())) {
				// 红孩子，超市，小店的督导，走这个分支，跳转卡单页面
				statisWapUrl = SCMConfigUtil.getConfig(ConfigConstants.FAST_S_EXP_ORDER_IDX_URL);
			} else {
				// 督导数据首页
				statisWapUrl = SCMConfigUtil.getConfig(ConfigConstants.STORE_GUIDE_STATIS_URL);
			}
		}

		indexShowData.setStatisWapUrl(statisWapUrl);
		indexShowData.setRealTimeSales(realTimeSales);
		return indexShowData;
	}

	@Override
	public ReturnMsg<String> updatePositionInfo(String roleType, String orgId, String positionName, String positionId, String staffid) {
		LOGGER.info("updatePositionInfo ,  positionName:{}, positionId:{},  staffid:{} ", positionName, positionId, staffid);
		ReturnMsg<String> returnMsg = new ReturnMsg<String>();
		boolean daoResult = this.storeInfoService.updatePositionInfo(roleType, orgId, positionName, positionId, staffid);
		if (!daoResult) {
			LOGGER.error("updatePositionInfo daoResult for false  positionName:{}, positionId:{},  staffid:{} ", positionName, positionId, staffid);
			returnMsg.setError(ErrorCodeConstants.ERR_0002);
			return returnMsg;
		}
		final String key = ATTACH_INFO_PREFIX + staffid;
		jedisClient.execute(new JedisAction<Long>() {
			@Override
			public Long doAction(Jedis jedis) {
				return jedis.del(key);
			}
		});
		// 通知POSTS删除登录缓存信息
		postsAuthService.removePostsLoginCache(staffid);
		return returnMsg;
	}

}
